import {
    EventKey
} from "../common_for_guosheng/Key";
import {
    S_CELL_GS_WIDTH,
    S_CELL_FALL_SPEED,
    GAME_STATE,
    GAMEMODEGS,
    MAX_SCOREGS,
    GetGameGridCount,
    IsSH
} from "./GameGSDefine";
import GridGSModel from "./GridGSModel";
// import { EventKey } from "../common/Key";
import {
    GameGSState
} from "./GameGSState";
import {
    GameGSData
} from "./GameGSData";

import SodaCommon from "../soda/SodaCommon";

import SodaEventSoda from "../soda/SodaEventSoda";

var GridGSView = cc.Class({
    extends: cc.Component,

    statics: {
        instance: null,
    },

    properties: {
        TaDie: cc.Node,
        TaTaDie: cc.Node,
        SBPro: cc.ProgressBar,
        labScore: cc.Label,
        SB2: cc.Label,
        sb34: cc.Label,
        TABaBa: cc.Node,
        wori_barPro: cc.Node,
        tongGuanJieDian: cc.Node,
        PiaoFen: cc.Node,
        leftCount: cc.Label,
        MDsCORse: cc.Label,
    },

    onLoad() {
        GridGSView.instance = this;
        this.TABaBa.on('touchstart', this._onTMDjStart, this);

        F.OnEvent.on(EventKey.EVENT_ADD_SCORE, this._onTMDShiJianJT, this);
        F.OnEvent.on(EventKey.EVENT_PASS_LEVEL, this._onTMDShiJianJT, this);
        F.OnEvent.on(EventKey.EVENT_RECOVER_CELL, this._onTMDShiJianJT, this);
        F.OnEvent.on(EventKey.EVENT_RETRY, this._onTMDShiJianJT, this);
        F.OnEvent.on(EventKey.EVENT_SAVE_GAME_DATA, this._onTMDShiJianJT, this);

        // GameGSState.init();
        this._KaiShiYouXi();

        this._updateSBPro();
        this._updateScore();
    },

    onDestroy() {
        F.OnEvent.off(EventKey.EVENT_ADD_SCORE, this._onTMDShiJianJT, this);
        F.OnEvent.off(EventKey.EVENT_PASS_LEVEL, this._onTMDShiJianJT, this);
        F.OnEvent.off(EventKey.EVENT_RECOVER_CELL, this._onTMDShiJianJT, this);
        F.OnEvent.off(EventKey.EVENT_RETRY, this._onTMDShiJianJT, this);
        F.OnEvent.off(EventKey.EVENT_SAVE_GAME_DATA, this._onTMDShiJianJT, this);
    },

    _onTMDShiJianJT(eventName, param) {
        if (eventName == EventKey.EVENT_ADD_SCORE) {
            this._addScore(param.score);
        } else if (eventName == EventKey.EVENT_PASS_LEVEL) {
            this._showPassLevel();
        } else if (eventName == EventKey.EVENT_RECOVER_CELL) {
            this._putAllCellIntoPool();
        } else if (eventName == EventKey.EVENT_RETRY) {
            this._KaiShiYouXi();
        } else if (eventName == EventKey.EVENT_SAVE_GAME_DATA) {
            this.gridModel.saveLastGame();
        }
    },
    // 
    _KaiShiYouXi() {
        let gameMode = GameGSData.getGameMode();
        let params = null;
        if (gameMode == GAMEMODEGS.DEFAULT) {
            // 正常开局
        } else if (gameMode == GAMEMODEGS.BESTSCORE) {
            // 从最高纪录开始
            params = {
                level: GameGSData.getBestLevel(),
                score: GameGSData.getBestScore(),
            }
        } else if (gameMode == GAMEMODEGS.CONTINUE) {
            // 从上次退出的地方开始
            params = GameGSData.getChallengeData();
        }

        this.gameState = GAME_STATE.OVER;
        this.gridModel = new GridGSModel(params);
        // F.OnEvent.fire(EventKey.EVENT_NEXT_LEVEL);
        this._XiaYiGuan();
        this._updateSBPro();
        this._GenXinFenShu();
        this._GenXinGuanShu();
        this._bofangXiaLuoTeXiao();
    },

    _KaiShiXiaYiGuan() {
        this.gameState = GAME_STATE.OVER;
        this.gridModel = new GridGSModel();
        // F.OnEvent.fire(EventKey.EVENT_NEXT_LEVEL);
        this._XiaYiGuan();
        this._updateSBPro();
        this._GenXinFenShu();
        this._GenXinGuanShu();
        this._bofangXiaLuoTeXiao();
    },

    _XiaYiGuan() {
        if (cc.sys.browserType === cc.sys.BROWSER_TYPE_WECHAT_GAME) {
            if (parseInt(GameGSState.getLevel()) === parseInt(SodaCommon.userData.guan)) {
                SodaCommon.userAddIntegral().then((res) => {
                    GameGSState.setLevel(SodaCommon.userData.guan);
                    SodaEventSoda.emit(SodaEventSoda.USER_ADD_INTEGRAL, res);
                });
            }
        } else {
            SodaEventSoda.emit(SodaEventSoda.USER_ADD_INTEGRAL);
        }
    },

    _bofangXiaLuoTeXiao() {
        if (!IsSH()) {
            this._texiao0();
            return;
        }
        let type = F.Utils.random(1, 4);
        if (type == 1) {
            this._texiao1();
        } else if (type == 2) {
            this._texiao2();
        } else if (type == 3) {
            this._texiao3();
        } else if (type == 4) {
            this._texiao4();
        }
    },

    _GenXinFenShu() {
        this.SB2.string = '' + this.gridModel.getLevelScore();
    },
    _GenXinGuanShu() {
        this.sb34.string = GameGSState.getLevelDes();
    },

    _texiao0() {
        let cellModels = this.gridModel.getCellGSModels();
        this.cellNodes = [];
        let count = GetGameGridCount();
        for (let y = 0; y < count; y++) {
            this.cellNodes[y] = [];
            for (let x = 0; x < count; x++) {
                if (!cellModels[y][x]) {
                    continue;
                }
                let node = F.Utils.getPoolFuckNode('nodePoolCell');
                node.parent = this.TaDie;
                node.getComponent('CellGSView').init(cellModels[y][x]);
                this.cellNodes[y][x] = node;
            }
        }
        this.gameState = GAME_STATE.WAITTING;
    },
    // 效果1,从小到大
    _texiao1() {
        let cellModels = this.gridModel.getCellGSModels();
        this.cellNodes = [];
        let count = GetGameGridCount();

        for (let y = 0; y < count; y++) {
            this.cellNodes[y] = [];
            for (let x = 0; x < count; x++) {
                if (!cellModels[y][x]) {
                    continue;
                }
                let node = F.Utils.getPoolFuckNode('nodePoolCell');
                node.parent = this.TaDie;
                node.getComponent('CellGSView').init(cellModels[y][x]);
                this.cellNodes[y][x] = node;
                node.scale = 0;
                cc.tween(node)
                    .delay(0.2)
                    .to(0.2, {
                        scale: 1
                    })
                    .start()
            }
        }
        this.scheduleOnce(() => {
            this.gameState = GAME_STATE.WAITTING;
        }, 0.4)
    },
    // 效果2，渐显
    _texiao2() {
        let cellModels = this.gridModel.getCellGSModels();
        this.cellNodes = [];
        let count = GetGameGridCount();
        for (let y = 0; y < count; y++) {
            this.cellNodes[y] = [];
            for (let x = 0; x < count; x++) {
                if (!cellModels[y][x]) {
                    continue;
                }
                let node = F.Utils.getPoolFuckNode('nodePoolCell');
                node.parent = this.TaDie;
                node.getComponent('CellGSView').init(cellModels[y][x]);
                this.cellNodes[y][x] = node;
                node.opacity = 0;
                cc.tween(node)
                    .delay(0.2)
                    .to(1, {
                        opacity: 255
                    })
                    .start()
            }
        }
        this.scheduleOnce(() => {
            this.gameState = GAME_STATE.WAITTING;
        }, 1.2)
    },
    // 效果3，上方落下,一排排
    _texiao3() {
        let cellModels = this.gridModel.getCellGSModels();
        this.cellNodes = [];
        let count = GetGameGridCount();

        for (let y = 0; y < count; y++) {
            this.cellNodes[y] = [];
            for (let x = 0; x < count; x++) {
                if (!cellModels[y][x]) {
                    continue;
                }
                let node = F.Utils.getPoolFuckNode('nodePoolCell');
                node.parent = this.TaDie;
                node.getComponent('CellGSView').init(cellModels[y][x]);
                this.cellNodes[y][x] = node;
                let relY = node.y;
                node.y = 1000;
                let t = 0.1 * y;
                this.scheduleOnce(() => {
                    cc.tween(node)
                        .to(0.3, {
                            y: relY
                        })
                        .start()
                }, t)
            }
        }
        this.scheduleOnce(() => {
            this.gameState = GAME_STATE.WAITTING;
        }, 1.3)
    },

    _texiao4() {
        let cellModels = this.gridModel.getCellGSModels();
        this.cellNodes = [];
        let count = GetGameGridCount();
        for (let y = 0; y < count; y++) {
            this.cellNodes[y] = [];
            for (let x = 0; x < count; x++) {
                if (!cellModels[y][x]) {
                    continue;
                }
                let node = F.Utils.getPoolFuckNode('nodePoolCell');
                node.parent = this.TaDie;
                node.getComponent('CellGSView').init(cellModels[y][x]);
                this.cellNodes[y][x] = node;
                let relX = node.x;
                node.x = -relX;
                let relY = node.y;
                node.y = 600;
                node.opacity = 0;

                let t = 0.1 * y;
                this.scheduleOnce(() => {
                    cc.tween(node)
                        .to(0.3, {
                            position: cc.v2(relX, relY),
                            opacity: 255
                        })
                        .start()
                }, t)
            }
        }
        this.scheduleOnce(() => {
            this.gameState = GAME_STATE.WAITTING;
        }, 1.3)
    },

    // 点击
    _onTMDjStart(event) {
        if (this.gameState === GAME_STATE.OVER ||
            this.gameState === GAME_STATE.GATHERING || this.gameState === GAME_STATE.ELIMINATING || this.gameState === GAME_STATE.FALLING) {
            return;
        }
        // 判断点击位置，选中格子
        let touchPos = this.TaDie.convertToNodeSpaceAR(event.getLocation());
        if (!touchPos) {
            return;
        }

        let x = Math.floor(touchPos.x / S_CELL_GS_WIDTH) + 5;
        let y = Math.floor(touchPos.y / S_CELL_GS_WIDTH) + 5;
        let count = GetGameGridCount();
        // 越界
        if (x > count || x < 0 || y > count || y < 0) {
            return;
        }

        let list = this.gridModel.clickCell(x, y);
        this._xiaoChuFangKuai(list);
    },

    // 消除方块
    _xiaoChuFangKuai(list) {
        if (list.length < 2) {
            return;
        }
        this.gameState = GAME_STATE.ELIMINATING;
        this.gridModel.removeCellGSModelByList(list);

        let maxSpace = 0;
        for (let i = 0; i < list.length; i++) {
            let cellModel = list[i];
            let node = this.cellNodes[cellModel.y][cellModel.x];
            this.cellNodes[cellModel.y][cellModel.x] = null;
            if (cellModel.space > maxSpace) {
                maxSpace = cellModel.space;
            }
            this.scheduleOnce(function (cellModel, node) {
                F.Game.gameAudioGS.playPop();
                F.GSPartner.vibrateShort();
                node.getComponent('CellGSView').recoverCellNode();
                this._playParticle(cellModel.color, cellModel.x, cellModel.y);
                this._addNodeScore(list.length, cellModel.x, cellModel.y);
            }.bind(this, cellModel, node), i * 0.1)
        }

        this._addNodeCombo(list.length);

        this.scheduleOnce(() => {
            this._onEliminateDone();
        }, list.length * 0.1)
    },

    _onEliminateDone() {
        this._fallDown();
    },

    // 下落
    _fallDown() {
        if (this.gameState === GAME_STATE.OVER) {
            return;
        }
        this.gridModel.cellFall();
        let cellModels = this.gridModel.getCellGSModels();
        let hadFalled = false;
        for (let y = 0; y < cellModels.length; y++) {
            for (let x = 0; x < cellModels[y].length; x++) {
                let cellModel = cellModels[y][x];
                if (!cellModel) {
                    continue;
                }
                if (cellModel.fallCount <= 0) {
                    continue;
                }
                hadFalled = true;
                let fallCount = cellModel.fallCount;
                cellModel.fallCount = 0;
                let yy = y + fallCount;
                let cellNode = this.cellNodes[yy][x];
                this.cellNodes[yy][x] = null;
                this.cellNodes[y][x] = cellNode;
                cellNode.getComponent('CellGSView').playFallEffect(y);
            }
        }

        if (hadFalled) {
            this.gameState = GAME_STATE.FALLING;
            this.scheduleOnce(() => {
                this._fallDownDone();
            }, S_CELL_FALL_SPEED);
        } else {
            this._fallDownDone();
        }
    },

    _fallDownDone() {
        this._gather();
    },

    // 聚拢
    _gather() {
        if (this.gameState === GAME_STATE.OVER) {
            return;
        }
        this.gridModel.cellGather();
        let cellModels = this.gridModel.getCellGSModels();
        let hadGather = false;
        for (let y = 0; y < cellModels.length; y++) {
            for (let x = 0; x < cellModels[y].length; x++) {
                let cellModel = cellModels[y][x];
                if (!cellModel) {
                    continue;
                }
                if (cellModel.gatherCount <= 0) {
                    continue;
                }
                hadGather = true;
                let gatherCount = cellModel.gatherCount;
                cellModel.gatherCount = 0;
                let xx = x + gatherCount;
                let cellNode = this.cellNodes[y][xx];
                this.cellNodes[y][xx] = null;
                this.cellNodes[y][x] = cellNode;
                cellNode.getComponent('CellGSView').playGatherEffect(x);
            }
        }
        if (hadGather) {
            this.gameState = GAME_STATE.GATHERING;
            this.scheduleOnce(() => {
                this._gatherDone();
            }, S_CELL_FALL_SPEED);
        } else {
            this._gatherDone();
        }
    },

    _gatherDone() {
        this._checkIsOver();
    },

    // 检查是否结束
    _checkIsOver() {
        if (this.gameState === GAME_STATE.OVER) {
            return;
        }
        let isOver = this.gridModel.checkIsOver();
        if (isOver) {
            this.gameState = GAME_STATE.OVER;
            this._starBomb();
        } else {
            this.gameState = GAME_STATE.WAITTING;
        }
    },

    _starBomb() {
        let arr = [];
        let cellModels = this.gridModel.getCellGSModels();
        for (let y = cellModels.length - 1; y >= 0; y--) {
            for (let x = 0; x < cellModels[y].length; x++) {
                let cellModel = cellModels[y][x];
                if (!cellModel) {
                    continue;
                }
                arr.push(cellModel);
            }
        }
        let count = GetGameGridCount();
        let maxCount = count;
        if (arr.length < count) {
            maxCount = arr.length;
        }
        for (let i = 0; i < maxCount; i++) {
            let cellModel = arr[i];
            arr[i] = null;
            let node = this.cellNodes[cellModel.y][cellModel.x];
            this.scheduleOnce(function (cellModel, node) {
                F.Game.gameAudioGS.playPop();
                F.GSPartner.vibrateShort();
                node.getComponent('CellGSView').recoverCellNode();
                this._playParticle(cellModel.color, cellModel.x, cellModel.y);
            }.bind(this, cellModel, node), i * 0.1)
        }

        if (arr.length > count) {
            this.scheduleOnce(() => {
                F.Game.gameAudioGS.playBomb();
                F.GSPartner.vibrateLong();
                for (let i = 0; i < arr.length; i++) {
                    if (arr[i]) {
                        let cellModel = arr[i];
                        let node = this.cellNodes[cellModel.y][cellModel.x];
                        node.getComponent('CellGSView').recoverCellNode();
                        this._playParticle(cellModel.color, cellModel.x, cellModel.y);
                    }
                }
            }, maxCount * 0.1 + 0.1)
        }


        this.scheduleOnce(() => {
            this._showBonus();
        }, arr.length * 0.1 + 0.1)
    },

    _showBonus() {
        let arr = [];
        let cellModels = this.gridModel.getCellGSModels();
        for (let y = cellModels.length - 1; y >= 0; y--) {
            for (let x = 0; x < cellModels[y].length; x++) {
                let cellModel = cellModels[y][x];
                if (!cellModel) {
                    continue;
                }
                arr.push(cellModel);
            }
        }

        let leftCount = arr.length;
        let score = this.gridModel.getBonusScore(leftCount);

        this.leftCount.string = '剩余个数：' + leftCount;
        this.MDsCORse.string = '奖励分数：' + score;
        this.PiaoFen.active = true;
        this.PiaoFen.x = -400;
        let action = cc.sequence(
            cc.moveTo(0.5, 0, this.PiaoFen.y),
            cc.delayTime(1),
            cc.callFunc(() => {
                this.PiaoFen.active = false;
                F.OnEvent.fire(EventKey.EVENT_ADD_SCORE, {
                    score: score
                });
                GameGSState.addLevel();
                this.gridModel.clearCellGSModels();
                let param = {
                    result: this.gridModel.getIsPass(),
                    func1: this._KaiShiXiaYiGuan.bind(this),
                }
                F.Ui.openUI('PanelScore', param);
            })
        )
        this.PiaoFen.runAction(action);
    },

    _getCellGSModel(x, y) {
        if (!this.cellNodes[y]) {
            return false;
        }
        return this.cellNodes[y][x];
    },


    _playParticle(color, x, y) {
        let node = F.Utils.getPoolFuckNode('nodePoolParticle');
        node.parent = this.TaTaDie;
        node.getComponent('ItemParticle').init(color, x, y);
    },
    _addNodeScore(count, x, y) {
        let score = count * 5;
        if (score * count >= MAX_SCOREGS) {
            score = Math.floor(MAX_SCOREGS / count);
        }
        this.scheduleOnce(() => {
            let node = F.Utils.getPoolFuckNode('nodePoolScore');
            node.parent = this.TaTaDie;
            let worldPos = this.wori_barPro.parent.convertToWorldSpaceAR(this.wori_barPro.position);
            let targetPos = this.TaTaDie.convertToNodeSpaceAR(worldPos);
            node.getComponent('ItemScore').init(score, x, y, targetPos);
        }, 0.2)
    },
    _addNodeCombo(count) {
        if (count <= 5) {
            return;
        }
        this.scheduleOnce(() => {
            let node = F.Utils.getPoolFuckNode('nodePoolCombo');
            node.parent = this.TaTaDie;
            node.getComponent('ItemGSCombo').init(count);
        }, 0.2)
    },

    _addScore(score) {
        GameGSState.addScore(score);
        this.gridModel.checkPass();
        this._updateSBPro();
        this._updateScore();
    },

    _updateSBPro() {
        let progress = GameGSState.getScore() / this.gridModel.getLevelScore();
        if (progress > 1) {
            progress = 1;
        }
        this.SBPro.progress = progress;
    },

    _updateScore() {
        this.labScore.string = GameGSState.getScore();
    },

    _showPassLevel() {
        let node = F.Utils.getPoolFuckNode('nodePoolPassTip');
        node.parent = this.TaTaDie;
        let worldPos = this.tongGuanJieDian.parent.convertToWorldSpaceAR(this.tongGuanJieDian.position);
        let targetPos = this.TaTaDie.convertToNodeSpaceAR(worldPos);
        node.getComponent('ItemPassTip').init(targetPos);
        F.Game.gameAudioGS.playSucc();
    },

    _putAllCellIntoPool() {
        let count = GetGameGridCount();
        for (let y = 0; y < count; y++) {
            for (let x = 0; x < count; x++) {
                let node = this.cellNodes[y][x];
                if (node) {
                    F.Utils.putPoolFuckNode('nodePoolCell', node);
                }
            }
        }
    },

    _shuffleBoard() {
        let oldArr = this.gridModel.shuffleBoard();
        let count = GetGameGridCount();
        for (let y = 0; y < count; y++) {
            for (let x = 0; x < count; x++) {
                let cellModel = oldArr[y][x];
                if (!cellModel) {
                    continue;
                }
                let node = this.cellNodes[y][x];
                if (node) {
                    node.getComponent('CellGSView').moveTo(x, y);
                }
            }
        }

        let tArr = this.cellNodes;
        this.cellNodes = [];

        for (let y = 0; y < count; y++) {
            this.cellNodes[y] = [];
        }
        for (let y = 0; y < count; y++) {
            for (let x = 0; x < count; x++) {
                let node = tArr[y][x];
                if (!node) {
                    continue;
                }
                let cellModel = oldArr[y][x];
                let pos = cellModel.getXY();
                this.cellNodes[pos.y][pos.x] = node;
            }
        }
    },

    _destroyOneCell(x, y) {
        let cellModel = this.gridModel.destroyOneCell(x, y);
        if (!cellModel) {
            return;
        }

        let node = this.cellNodes[y][x];
        F.Game.gameAudioGS.playPop();
        F.GSPartner.vibrateShort();
        node.getComponent('CellGSView').recoverCellNode();
        this._playParticle(cellModel.color, cellModel.x, cellModel.y);
    },

    _changeColor(x, y, color) {
        let cellModel = this.gridModel.changeColor(x, y, color);
        if (!cellModel) {
            return;
        }
        let node = this.cellNodes[y][x];
        node.getComponent('CellGSView').setColor(color);
    },
});